package com.reactsdk.sid.elk

import android.view.Choreographer
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import androidx.fragment.app.FragmentActivity
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReadableArray
import com.facebook.react.uimanager.ThemedReactContext
import com.facebook.react.uimanager.ViewGroupManager
import com.facebook.react.uimanager.annotations.ReactPropGroup
import sberid.sdk.ui.screens.view.elk.fragment.ELKBlockFragment

class SIDELKManager(private var reactContext: ReactApplicationContext) : ViewGroupManager<FrameLayout>() {

	private var propWidth = DEFAULT_SIZE
	private var propHeight = DEFAULT_SIZE
	override fun getName(): String = CLASS_NAME

	/**
	 * Return a FrameLayout which will later hold the Fragment
	 */
	public override fun createViewInstance(reactContext: ThemedReactContext): FrameLayout {
		return FrameLayout(reactContext)
	}

	/**
	 * Map the "create" command to an integer
	 */
	override fun getCommandsMap(): Map<String, Int> = mapOf(CREATE to COMMAND_CREATE)

	/**
	 * Handle "create" command (called from JS) and call createFragment method
	 */
	override fun receiveCommand(
		root: FrameLayout,
		commandId: String,
		args: ReadableArray?
	) {
		super.receiveCommand(root, commandId, args)
		val reactNativeViewId = args?.getInt(VIEW_ID_REACT) ?: return
		val commandIdInt = commandId.toInt()
		when (commandIdInt) {
			COMMAND_CREATE -> createFragment(root, reactNativeViewId)
			else -> Unit
		}
	}

	@ReactPropGroup(names = [WIDTH, HEIGHT], customType = CUSTOM_TYPE)
	fun setStyle(view: FrameLayout?, index: Int, value: Int) {
		when(index){
			PROP_WIDTH -> propWidth = value
			PROP_HEIGHT -> propHeight = value
		}
	}

	/**
	 * Replace your React Native view with a custom fragment
	 */
	private fun createFragment(root: FrameLayout, reactNativeViewId: Int) {
		val parentView = root.findViewById<ViewGroup>(reactNativeViewId)
		setupLayout(parentView)
		val myFragment = ELKBlockFragment()
		val activity = reactContext.currentActivity as? FragmentActivity ?: return
		activity.supportFragmentManager
			.beginTransaction()
			.replace(reactNativeViewId, myFragment, reactNativeViewId.toString())
			.commit()
	}

	private fun setupLayout(view: View) {
		Choreographer.getInstance().postFrameCallback(object : Choreographer.FrameCallback {
			override fun doFrame(frameTimeNanos: Long) {
				manuallyLayoutChildren(view)
				view.viewTreeObserver.dispatchOnGlobalLayout()
				Choreographer.getInstance().postFrameCallback(this)
			}
		})
	}

	/**
	 * Layout all children properly
	 */
	fun manuallyLayoutChildren(view: View) {
		// propWidth and propHeight coming from react-native props
		val width = propWidth
		val height = propHeight
		view.measure(
			View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY),
			View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY)
		)
		view.layout(DEFAULT_POSITION, DEFAULT_POSITION, width, height)
	}

	companion object {
		private const val CLASS_NAME = "SIDELKManager"
		private const val COMMAND_CREATE = 1
		private const val CREATE = "create"
		private const val WIDTH = "width"
		private const val HEIGHT = "height"
		private const val CUSTOM_TYPE = "Style"
		private const val DEFAULT_SIZE = 0
		private const val DEFAULT_POSITION = 0
		private const val VIEW_ID_REACT = 0
		private const val PROP_WIDTH = 0
		private const val PROP_HEIGHT = 1
	}
}